from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QResizeEvent, QValidator, QIntValidator
from PySide6.QtWidgets import *
from qfluentwidgets import (PillPushButton, SimpleCardWidget, FlowLayout, SubtitleLabel, ScrollArea, PushButton,
                            InfoBar, SpinBox, ComboBox, LineEdit, StateToolTip, TransparentToolButton, FluentIcon)
from common import (GeographicInformation, BasicInformation, EmailInformation, NetInformation, BrowserInformation,
                    NumericalInformation, TextEncryption, ExcelRandomDataThread)
from components import SaveCard, OpenFileDialog


class AppCord(QFrame):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.vBox = QVBoxLayout(self)
        self.vBox.setContentsMargins(0, 0, 0, 0)
        self.vBox.setSpacing(10)
        self.vBox.setAlignment(Qt.AlignmentFlag.AlignTop)

        self.title = SubtitleLabel()
        self.frame = SimpleCardWidget()

        self.layout = FlowLayout(self.frame)
        self.layout.setContentsMargins(5, 10, 5, 10)
        self.layout.setSpacing(10)

        self.vBox.addWidget(self.title)
        self.vBox.addWidget(self.frame)

    def setTitle(self, title):
        self.title.setText(title)

    def addItem(self, widget):
        self.layout.addWidget(widget)

    def addItems(self, items: list):
        for item in items:
            self.addItem(item)

    def addButton(self, text):
        but = PillPushButton()
        but.setText(text)
        self.addItem(but)

    def addButtons(self, buttons: list):
        for button in buttons:
            self.addButton(button)

    def getSelectButton(self):
        buttonText = []
        for button in self.findChildren(PillPushButton):  # type: PillPushButton
            if button.isChecked():
                buttonText.append(button.text())
        return buttonText


class RandomExcelFrame(ScrollArea):
    returned = Signal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.scrollWidget = QWidget()
        self.setStyleSheet('QWidget{background-color: transparent; border:none;}')
        self.vBox = QVBoxLayout(self.scrollWidget)

        self.returnButton = TransparentToolButton(FluentIcon.RETURN, self)
        self.returnButton.setFixedSize(40, 40)
        self.returnButton.move(10, 5)
        self.returnButton.clicked.connect(self.returned.emit)

        self.basicInfo = AppCord()
        self.basicInfo.setTitle("基础信息类")
        self.basicInfo.addButtons(BasicInformation.values())

        self.geoInfo = AppCord()
        self.geoInfo.setTitle("地理信息类")
        self.geoInfo.addButtons(GeographicInformation.values())

        self.emailInfo = AppCord()
        self.emailInfo.setTitle("邮箱信息类")
        self.emailInfo.addButtons(EmailInformation.values())

        self.netInfo = AppCord()
        self.netInfo.setTitle("网络基础信息类")
        self.netInfo.addButtons(NetInformation.values())

        self.browserInfo = AppCord()
        self.browserInfo.setTitle("浏览器信息类")
        self.browserInfo.addButtons(BrowserInformation.values())

        self.numInfo = AppCord()
        self.numInfo.setTitle("数字信息")
        self.numInfo.addButtons(NumericalInformation.values())

        self.textInfo = AppCord()
        self.textInfo.setTitle("文本加密类")
        self.textInfo.addButtons(TextEncryption.values())

        self.saveCard = SaveCard(self)
        self.saveCard.setFixedHeight(30)
        self.saveCard.setButtonText('开始')

        self.rows = LineEdit()
        self.rows.setValidator(QIntValidator())
        self.rows.setFixedSize(120, 30)
        self.rows.setPlaceholderText('数据行数')
        self.rows.setClearButtonEnabled(True)
        self.saveCard.addWidget(self.rows)
        self.comboBox = ComboBox()
        self.comboBox.addItems(['中文', '英语'])
        self.comboBox.setFixedSize(80, 30)
        self.saveCard.addWidget(self.comboBox)

        self.stateToolTip = StateToolTip('随机数据', '正在生成随机数据，请稍后...', self)
        self.stateToolTip.hide()
        self.dataThread = ExcelRandomDataThread(self)

        self.dataThread.started.connect(self.stateToolTip.show)
        self.dataThread.error.connect(self.thread_error)
        self.dataThread.finished.connect(self.thread_finished)
        self.saveCard.clicked.connect(self.startButtonEvent)
        self.saveCard.saved.connect(self.save_event)

        self.__initWidget()

    def __initWidget(self):
        self.resize(1000, 800)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setViewportMargins(0, 50, 0, 0)
        self.setWidget(self.scrollWidget)
        self.setWidgetResizable(True)

        # initialize layout
        self.__initLayout()

    def __initLayout(self):
        # 添加设置卡组到布局中
        self.vBox.setSpacing(10)
        self.vBox.setContentsMargins(10, 10, 10, 10)
        self.vBox.setAlignment(Qt.AlignmentFlag.AlignTop)

        self.vBox.addWidget(self.basicInfo)
        self.vBox.addWidget(self.geoInfo)
        self.vBox.addWidget(self.emailInfo)
        self.vBox.addWidget(self.netInfo)
        self.vBox.addWidget(self.browserInfo)
        self.vBox.addWidget(self.numInfo)
        self.vBox.addWidget(self.textInfo)

    def _get_column(self):
        basic_en = self.basicInfo.getSelectButton()
        basic_zh = [BasicInformation.value_dict()[text] for text in basic_en]
        geo_en = self.geoInfo.getSelectButton()
        geo_zh = [GeographicInformation.value_dict()[text] for text in geo_en]
        email_en = self.emailInfo.getSelectButton()
        email_zh = [EmailInformation.value_dict()[text] for text in email_en]
        net_en = self.netInfo.getSelectButton()
        net_zh = [NetInformation.value_dict()[text] for text in net_en]
        browser_en = self.browserInfo.getSelectButton()
        browser_zh = [BrowserInformation.value_dict()[text] for text in browser_en]
        num_en = self.numInfo.getSelectButton()
        num_zh = [NumericalInformation.value_dict()[text] for text in num_en]
        text_en = self.textInfo.getSelectButton()
        text_zh = [TextEncryption.value_dict()[text] for text in text_en]

        zh = basic_en + geo_en + email_en + net_en + browser_en + num_en + text_en
        en = basic_zh + geo_zh + email_zh + net_zh + browser_zh + num_zh + text_zh
        return en, zh

    def startButtonEvent(self):
        en, zh = self._get_column()
        path = self.saveCard.lineText()
        rows = self.rows.text()
        language = self.comboBox.currentText()

        if path == '':
            return
        if rows == '':
            InfoBar.warning('提示', '请输入数据行数', parent=self)
            return

        if len(en) == 0 or len(zh) == 0:
            InfoBar.warning('提示', '请选择字段数据', parent=self)
            return

        _language = 'zh_CN'
        if language == '中文':
            _language = 'zh_CN'
        elif language == '英语':
            _language = 'english'

        self.dataThread.set_value(
            columns=en,
            rows=int(rows),
            path=path,
            language=_language,
            re_columns=zh
        )
        self.dataThread.start()

    def resizeEvent(self, event: QResizeEvent):
        self.saveCard.move(60, 10)
        self.saveCard.resize(event.size().width() - 70, 40)
        self.stateToolTip.move(event.size().width() - self.stateToolTip.width() - 20, 10)
        super().resizeEvent(event)

    def save_event(self):
        file = OpenFileDialog(self).getSaveFileName('./fake2excel.xlsx', 'Excel文件(*.xlsx;*.xls)')
        self.saveCard.setLineText(file[0])

    def thread_error(self, msg):
        InfoBar.warning('错误', msg, duration=5000, parent=self)

    def thread_finished(self):
        self.stateToolTip.hide()
        InfoBar.success('提示', 'Excel文件生成成功', parent=self)


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    # widget = QWidget()
    # lay = QHBoxLayout(widget)
    card = RandomExcelFrame()
    # card.setTitle("Random Excel")
    # card.addButton("Random")
    # lay.addWidget(card)
    card.show()
    sys.exit(app.exec())
